#ifndef QLSDBCONNPOOL_H
#define QLSDBCONNPOOL_H

#include <QString>
#include <QtSql>
#include <QList>
#include <QMutex>

#include "qls_db_manager_global.h"

/*
 * 数据库连接池类（单例模式）
 * 单例模式：确保一个类只有一个实例，该类自己进行实例化，并且向整个系统提供这个实例
 */
class QLS_DB_MANAGER_EXPORT QLsDBConnPool
{
public:
    /* 构造函数 */
    QLsDBConnPool();
    /* 析构函数 */
    ~QLsDBConnPool();

    /* 获取数据库连接 */
    static QSqlDatabase getConnection();
    /* 释放数据库连接回连接池 */
    static void releaseConnection(QSqlDatabase connection);
    /* 关闭所有的数据库连接 */
    static void destoryConnectionPool();

    /* select语句 */
    static QSqlRecord *runOne(const QString &content);
    /* insert into语句和update语句 */
    static void runNo(const QString &content);
    /* select语句 */
    static QList<QSqlRecord> runAll(const QString &content);

    /* 获取数据库类型 */
    static QString getType();

private:
    /* 创建数据库连接 */
    QSqlDatabase createConnection(const QString &connectionName);
    /* 单例模式：获取数据库连接池对象 */
    static QLsDBConnPool &getInstance();

private:
    /* 数据库信息 */
    QString m_databaseType; /* 数据库类型 */
    QString m_hostName;     /* 主机地址 */
    quint32 m_port;         /* 端口号 */
    QString m_databaseName; /* 数据库名称 */
    QString m_username;     /* 访问账户 */
    QString m_password;     /* 访问密码 */

    /* 连接池配置信息 */
    QString m_type;      /* 数据库类型 */
    bool m_testOnBorrow; /* 从连接池获取一个连接时，取出是否检测 */
    QString m_testOnBorrowSQL; /* 取出检测的SQL语句 */
    int m_maxWaitTime;         /* 获取连接最大等待时间 */
    int m_waitInterval;        /* 尝试获取连接时等待间隔时间 */
    int m_maxConnectionCount;  /* 最大连接数 */
    bool m_isSQL;              /* 是否输出sql语句 */

    QList<QString> m_usedConnectionNames;   /* 已使用的数据库连接名 */
    QList<QString> m_unusedConnectionNames; /* 未使用的数据库连接名 */

    /* 多线程互斥 */
    static QMutex m_instanceMutex;
    static QWaitCondition m_waitConnection;
    /* 唯一一个实例 */
    static QLsDBConnPool *m_instance;
};

#endif // QLSDBCONNPOOL_H
